package com.uchiha.nova.mainService.controller;

import cn.hutool.core.util.ObjectUtil;
import com.uchiha.nova.core.tool.constant.RedisCacheConstants;
import com.uchiha.nova.core.model.dto.NovaOauthTokenDTO;
import com.uchiha.nova.core.model.dto.RefreshTokenDTO;
import com.uchiha.nova.core.model.entity.OauthClientDetails;
import com.uchiha.nova.core.tool.api.R;
import com.uchiha.nova.core.tool.support.BaseController;
import com.uchiha.nova.core.tool.util.AuthUtil;
import com.uchiha.nova.mainService.service.impl.FactoryForOauthToken;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.concurrent.TimeUnit;

/**
 * @Author 周林静
 * @Date 2025-03-24 16:27
 * @Version 1.0
 */
@RestController
@RequestMapping("/oauth")
@Slf4j
public class TokenController extends BaseController {

    @Resource
    FactoryForOauthToken factoryForOauthToken;

    @Resource
    RedisTemplate<String,Object> redisTemplate;

    @Value("${nova.oauth.token-key}")
    String tokenKey;

    @PostMapping("/token")
    public R getToken(@RequestBody NovaOauthTokenDTO dto) {
        if(ObjectUtil.isEmpty(dto.getGrantType())){
            return R.fail("grantType不能为空");
        }else if (ObjectUtil.isNotEmpty(dto.getGrantType())&&"pwd".equals(dto.getGrantType())){
            if(ObjectUtil.isEmpty(dto.getUsername())){
                return R.fail("username不能为空");
            }
            if(ObjectUtil.isEmpty(dto.getPassword())){
                return R.fail("password不能为空");
            }
        }

        OauthClientDetails clientDetails = (OauthClientDetails) redisTemplate.opsForValue().get(RedisCacheConstants.NOVA_OAUTH_CLIENT+dto.getClientId());
        String grantTypes = clientDetails.getAuthorizedGrantTypes();
        log.info("grantTypes:{}",grantTypes);
        if(!grantTypes.contains(dto.getGrantType())){
            return R.fail("该client不允许的grantType");
        }
        return factoryForOauthToken.getService(dto.getGrantType()).getToken(dto);
    }

    @PostMapping("/refresh_token")
    public R refreshToken(@RequestBody RefreshTokenDTO refreshTokenDTO) {
        R r = AuthUtil.refreshToken(refreshTokenDTO.getRefreshToken(), tokenKey);

        if(r.isSuccess()){
            OauthClientDetails clientDetails = (OauthClientDetails) redisTemplate.opsForValue().get(RedisCacheConstants.NOVA_OAUTH_CLIENT+refreshTokenDTO.getClientId());
            redisTemplate.delete(RedisCacheConstants.NOVA_OAUTH_TOKEN+refreshTokenDTO.getToken());
            String authToken = (String) r.getData();
            redisTemplate.opsForValue().set(RedisCacheConstants.NOVA_OAUTH_TOKEN+authToken,authToken,clientDetails.getAccessTokenValidity(), TimeUnit.SECONDS);
        }
        return r;
    }
}
